package com.joolun.web.controller.scrm;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.joolun.common.annotation.Anonymous;
import com.joolun.common.annotation.Log;
import com.joolun.common.constant.Constants;
import com.joolun.common.core.controller.BaseController;
import com.joolun.common.core.domain.AjaxResult;
import com.joolun.common.core.page.TableDataInfo;
import com.joolun.common.core.redis.RedisCache;
import com.joolun.common.enums.BusinessType;
import com.joolun.common.utils.DateUtils;
import com.joolun.common.utils.StringUtils;
import com.joolun.common.utils.poi.ExcelUtil;
import com.joolun.system.domain.*;
import com.joolun.system.domain.vo.EduLandWebsiteVo;
import com.joolun.system.service.IEduLandWebsiteService;
import com.joolun.web.controller.tool.AccessTokenUtils;
import com.joolun.weixin.entity.ScrmChannelRecordLog;
import com.joolun.weixin.service.*;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 投放计划Controller
 * 
 * @author joolun
 * @date 2025-03-10
 */
@RestController
@RequestMapping("/scrm/plan")
public class ScrmDeliveryPlanController extends BaseController
{
    @Autowired
    private IScrmDeliveryPlanService scrmDeliveryPlanService;

    @Autowired
    private IScrmPlanLinkService iScrmPlanLinkService;

    @Autowired
    private IEduLandWebsiteService eduLandWebsiteService;

    @Autowired
    private IEduLandWebsiteService iEduLandWebsiteService;

    @Autowired
    private RedisCache redisCache;

    @Value("${weixin.wechat-mini-app.appId}")
    private String wxMiniAppId;

    @Value("${weixin.wechat-mini-app.appSecret}")
    private String wxAppSecret;

    @Autowired
    private IScrmCustomerAcquisitionService iScrmCustomerAcquisitionService;
    @Autowired
    private IScrmChannelStatisticsService scrmChannelStatisticsService;
    @Autowired
    private  IScrmCustomerInfoService iScrmCustomerInfoService;
    @Autowired
    private IScrmChannelRecordLogService scrmChannelRecordLogService;


    /**
     * 查询投放计划列表
     */
    @GetMapping("/list")
    public TableDataInfo list(ScrmDeliveryPlan scrmDeliveryPlan)
    {
        startPage();
        List<ScrmDeliveryPlan> list = scrmDeliveryPlanService.selectScrmDeliveryPlanList(scrmDeliveryPlan);
        if(CollectionUtil.isEmpty(list)){
            return getDataTable(list);
        }
        List<Long> ids = list.stream().map(item->item.getId()).collect(Collectors.toList());
        List<Long> tempIds = list.stream().map(item->item.getTemplateId()).collect(Collectors.toList());

        List<EduLandWebsite> eduLandWebsiteList = iEduLandWebsiteService.list(Wrappers.lambdaQuery(EduLandWebsite.class).in(EduLandWebsite::getLandId,tempIds));
        Map<Long,Long> idAndStyleMap = eduLandWebsiteList.stream().collect(Collectors.toMap(EduLandWebsite::getLandId,EduLandWebsite::getLandStyle));

        // 获取投放计划的链接信息
        List<ScrmPlanLink> planLinks = iScrmPlanLinkService.list(Wrappers.lambdaQuery(ScrmPlanLink.class).in(ScrmPlanLink::getPlanId,ids));

        // 按 planId 分组，直接收集 ScrmPlanLink 对象
        Map<Long, List<ScrmPlanLink>> idLinksMap = planLinks.stream().collect(Collectors.groupingBy(ScrmPlanLink::getPlanId));
        list.forEach(plan -> {
            Long planId = plan.getId();
            // 直接获取 ScrmPlanLink 对象列表
            List<ScrmPlanLink> links = idLinksMap.get(planId);
            if (links != null) {
                // 假设 Plan 类有 setLinks 方法接受 List<ScrmPlanLink>
                plan.setLinks(links);
            }
            plan.setLandStyle(idAndStyleMap.get(plan.getTemplateId()));
        });
        // 原代码返回 List<String> 字符串数组链接
//        Map<Long, List<String>> idLinksMap = planLinks.stream().collect(Collectors.groupingBy(ScrmPlanLink::getPlanId,
//                Collectors.mapping(ScrmPlanLink::getUrlLink, Collectors.toList())));
//        list.forEach(plan ->{
//            Long planId = plan.getId();
//            List<String> links = idLinksMap.get(planId);
//            if (links != null) {
//                plan.setLinks(links);
//            }
//            plan.setLandStyle(idAndStyleMap.get(plan.getTemplateId()));
//        });
        return getDataTable(list);
    }


    /**
     * 查询投放计划列表
     */
    @GetMapping("/listno")
    public TableDataInfo listno(ScrmDeliveryPlan scrmDeliveryPlan)
    {
        List<ScrmDeliveryPlan> list = scrmDeliveryPlanService.selectScrmDeliveryPlanList(scrmDeliveryPlan);
        return getDataTable(list);
    }
    /**
     * 导出投放计划列表
     */
    @PreAuthorize("@ss.hasPermi('scrm:plan:export')")
    @Log(title = "投放计划", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, ScrmDeliveryPlan scrmDeliveryPlan)
    {
        List<ScrmDeliveryPlan> list = scrmDeliveryPlanService.selectScrmDeliveryPlanList(scrmDeliveryPlan);
        ExcelUtil<ScrmDeliveryPlan> util = new ExcelUtil<ScrmDeliveryPlan>(ScrmDeliveryPlan.class);
        util.exportExcel(response, list, "投放计划数据");
    }

    /**
     * 获取投放计划详细信息
     */
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id)
    {
        return success(scrmDeliveryPlanService.selectScrmDeliveryPlanById(id));
    }

    /**
     * 新增投放计划
     */
    @PreAuthorize("@ss.hasPermi('scrm:plan:add')")
    @Log(title = "投放计划", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody ScrmDeliveryPlan scrmDeliveryPlan)
    {
        System.out.println(scrmDeliveryPlan);
        scrmDeliveryPlan.setCreateBy(getUsername());
        return toAjax(scrmDeliveryPlanService.insertScrmDeliveryPlan(scrmDeliveryPlan));
    }


    /**
     * 复制投放计划
     */
    @PreAuthorize("@ss.hasPermi('scrm:plan:add')")
    @Log(title = "复制投放计划", businessType = BusinessType.INSERT)
    @PostMapping(value = "/copy")
    public AjaxResult copy(@RequestBody ScrmDeliveryPlan scrmDeliveryPlan) {
        Long id = scrmDeliveryPlan.getId();
        ScrmDeliveryPlan scrmDeliveryPlanAdd = scrmDeliveryPlanService.getById(id);
        scrmDeliveryPlanAdd.setId(null);
        scrmDeliveryPlanAdd.setPlanName(scrmDeliveryPlanAdd.getPlanName()+"COPY_"+(id.intValue()+1));
        return toAjax(scrmDeliveryPlanService.insertScrmDeliveryPlan(scrmDeliveryPlanAdd));
    }


    /**
     * 修改投放计划
     */
    @PreAuthorize("@ss.hasPermi('scrm:plan:edit')")
    @Log(title = "投放计划", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody ScrmDeliveryPlan scrmDeliveryPlan)
    {
        scrmDeliveryPlan.setCreateBy(getUsername());
        return toAjax(scrmDeliveryPlanService.updateScrmDeliveryPlan(scrmDeliveryPlan));
    }

    /**
     * 删除投放计划
     */
    @PreAuthorize("@ss.hasPermi('scrm:plan:remove')")
    @Log(title = "投放计划", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids)
    {
        return toAjax(scrmDeliveryPlanService.deleteScrmDeliveryPlanByIds(ids));
    }


    /**
     * 访问落地页
     */
    @GetMapping(value = "/m/{code}")
    @Anonymous
    public AjaxResult getInfo(@PathVariable("code") String shortCode) {
        ScrmPlanLink scrmPlanLink = iScrmPlanLinkService.getOne(Wrappers.lambdaQuery(ScrmPlanLink.class).eq(ScrmPlanLink::getShortCode,shortCode));
        if(scrmPlanLink == null){
            return AjaxResult.error(101,"链接异常");
        }
        // 投放计划id
        Long planId = scrmPlanLink.getPlanId();
        // 查询落地页显示配置
        EduLandWebsiteVo eduLandWebsiteVo = eduLandWebsiteService.selectTouFangId(planId);

        // 根据投放计划查询企微
        ScrmDeliveryPlan scrmDeliveryPlan = scrmDeliveryPlanService.getById(planId);
        // 微信外流程类型
        Integer processType = scrmDeliveryPlan.getProcessType();
        Long courseId = scrmDeliveryPlan.getCourseId();
        // 生成获客助手链接, 验证排期是否能正常接量，
        if(processType == 4 || processType == 5){
            ScrmCustomerAcquisition customerAcquisition =  iScrmCustomerAcquisitionService.getOne(Wrappers.lambdaQuery(ScrmCustomerAcquisition.class).eq(ScrmCustomerAcquisition::getCourseId,courseId));
            String schemeUrl = customerAcquisition.getLinkUrl()+"?customer_channel=XCHK-"+planId+"-"+customerAcquisition.getSchedulingId()+"&phoneNUmber=0";
            // 预设投放计划id和排期id
            eduLandWebsiteVo.setSchemeUrl(schemeUrl);
            logger.info("-----------获客链接-------------" + schemeUrl);
        } else{
            // -------------------redis可能未取到参数
            // 获取小程序跳转链接
            String accessToken = redisCache.getCacheObject(Constants.WX_ACCESS_TOKEN);
            if(StringUtils.isBlank(accessToken)){
                // 获取微信accessToken
                accessToken = AccessTokenUtils.getAccessToken(wxMiniAppId,wxAppSecret);
                logger.info("---redis为空则获取新的accessToken：{}",accessToken);
                redisCache.setCacheObject(Constants.WX_ACCESS_TOKEN,accessToken,360, TimeUnit.SECONDS);
            }
            String schemeUrl = AccessTokenUtils.getSchemeUrl(planId,processType,scrmPlanLink.getShortCode(),accessToken,"0");
            eduLandWebsiteVo.setSchemeUrl(schemeUrl);
        }
        // TODO:增加统计数据
        ScrmChannelStatistics scrmChannelStatistics = scrmChannelStatisticsService.getOne(Wrappers.lambdaQuery(ScrmChannelStatistics.class).eq(ScrmChannelStatistics::getPlanId,planId));
        if(scrmChannelStatistics == null ){
            scrmChannelStatistics = new ScrmChannelStatistics();
            scrmChannelStatistics.setPlanId(planId);
            scrmChannelStatistics.setExtCorpId(scrmDeliveryPlan.getExtCorpId());
            scrmChannelStatistics.setChannelName(scrmDeliveryPlan.getPlanName());
            scrmChannelStatistics.setSysUserId(scrmDeliveryPlan.getSysUserId());
            scrmChannelStatistics.setPvNum(1L);
            scrmChannelStatistics.setUvNum(0L);
            scrmChannelStatistics.setLzNum(0L);
            scrmChannelStatistics.setSmNum(0L);
            scrmChannelStatistics.setJvNum(0L);
            scrmChannelStatistics.setSrsyNum(0L);
            scrmChannelStatistics.setSmNum(0L);
            scrmChannelStatistics.setWomenNum(0L);
            scrmChannelStatistics.setMenNum(0L);
            scrmChannelStatistics.setTqNum(0L);
            scrmChannelStatisticsService.save(scrmChannelStatistics);
        }else {
            scrmChannelStatistics.setPvNum(scrmChannelStatistics.getPvNum() +1);
            scrmChannelStatisticsService.saveOrUpdate(scrmChannelStatistics);
        }
        eduLandWebsiteVo.setPlanId(planId);
        eduLandWebsiteVo.setPhoneNumber("0");
        // 添加行为记录
        ScrmChannelRecordLog scrmChannelRecordLog = new ScrmChannelRecordLog();
        scrmChannelRecordLog.setAddDate(DateUtils.getYMD());
        scrmChannelRecordLog.setAddTime(new Date());
        scrmChannelRecordLog.setType("PV");
        scrmChannelRecordLog.setExtCorpId(scrmDeliveryPlan.getExtCorpId());
        scrmChannelRecordLog.setPlanId(planId);
        scrmChannelRecordLogService.save(scrmChannelRecordLog);
        return success(eduLandWebsiteVo);
    }


    /**
     * 根据投放计划id查询二维码
     */
    @GetMapping(value = "/getWxContactCode")
    @Anonymous
    public AjaxResult getWxContactCode(Long planId,Long userId)
    {
        logger.info("------------根据planId投放计划id:{},查询返回二维码：{}",planId,userId);
        return success(scrmDeliveryPlanService.getWxContactCode(planId,userId));
    }


    /**
     * 更新留资统计数据-H5留资
     */
    @GetMapping(value = "/updateMobileStatis/{planId}")
    @Anonymous
    public AjaxResult updateMobileStatis(@PathVariable("planId")Long planId,String phoneNumber) {

        ScrmDeliveryPlan scrmDeliveryPlan = scrmDeliveryPlanService.getById(planId);
        Integer processType = scrmDeliveryPlan.getProcessType();
        Long courseId = scrmDeliveryPlan.getCourseId();

        String schemeUrl  = "";
        // 生成获客助手链接
        if(processType == 4 || processType == 5){
            ScrmCustomerAcquisition customerAcquisition =  iScrmCustomerAcquisitionService.getOne(Wrappers.lambdaQuery(ScrmCustomerAcquisition.class).eq(ScrmCustomerAcquisition::getCourseId,courseId));
            schemeUrl = customerAcquisition.getLinkUrl()+"?customer_channel=XCHK-"+planId+"-"+customerAcquisition.getSchedulingId()+"&phoneNUmber=0";
        } else{
            // 获取小程序跳转链接
            String accessToken = redisCache.getCacheObject(Constants.WX_ACCESS_TOKEN);
            if(StringUtils.isBlank(accessToken)){
                // 获取微信accessToken
                accessToken = AccessTokenUtils.getAccessToken(wxMiniAppId,wxAppSecret);
                logger.info("---redis为空则获取新的accessToken：{}",accessToken);
                redisCache.setCacheObject(Constants.WX_ACCESS_TOKEN,accessToken,7200, TimeUnit.SECONDS);
            }
            // 联系人企微码显示的课程编号
            String shortCode = scrmDeliveryPlan.getPlanName();
            schemeUrl = AccessTokenUtils.getSchemeUrl(planId,processType,shortCode,accessToken,phoneNumber);
        }
        // 更新留资统计数据
        ScrmChannelStatistics scrmChannelStatistics = scrmChannelStatisticsService.getOne(Wrappers.lambdaQuery(ScrmChannelStatistics.class).eq(ScrmChannelStatistics::getPlanId,planId));
        if(scrmChannelStatistics != null){
            scrmChannelStatistics.setLzNum(scrmChannelStatistics.getLzNum()+1);
        }
        // 根据手机号查询用户信息是否已经留资
        ScrmCustomerInfo scrmCustomerInfo = iScrmCustomerInfoService.getOne(Wrappers.lambdaQuery(ScrmCustomerInfo.class).eq(ScrmCustomerInfo::getPhoneNumber,phoneNumber));
        if (Objects.isNull(scrmCustomerInfo)) {
            // 用户不存在，新增用户
            scrmCustomerInfo = new ScrmCustomerInfo();
            scrmCustomerInfo.setCreatedAt(new Date());
            scrmCustomerInfo.setPlanId(planId);
            scrmCustomerInfo.setPhoneNumber(phoneNumber);
            iScrmCustomerInfoService.save(scrmCustomerInfo);
            scrmChannelStatistics.setUvNum(scrmChannelStatistics.getUvNum() +1);
            scrmChannelRecordLogService.add(planId,"",scrmDeliveryPlan.getExtCorpId(),"UV");

        }
        scrmChannelStatisticsService.saveOrUpdate(scrmChannelStatistics);
        // 添加行为记录-留资
        scrmChannelRecordLogService.add(planId,"",scrmDeliveryPlan.getExtCorpId(),"LiuZi");
        return AjaxResult.success("",schemeUrl);
    }


}
